﻿<!--
// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
-->

<UserControl x:Class="System.Windows.Controls.Samples.SearchSuggestionSample"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:system="clr-namespace:System;assembly=mscorlib"
    xmlns:samplesCommon="clr-namespace:System.Windows.Controls.Samples;assembly=System.Windows.Controls.Samples.Common"
    xmlns:input="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input">

    <UserControl.Resources>
        <Style x:Key="SearchTextBoxStyle" TargetType="TextBox">
            <Setter Property="Background" Value="#AAFFFFFF" />
            <Setter Property="FontFamily" Value="Verdana" />
            <Setter Property="FontSize" Value="18" />
            <Setter Property="Padding" Value="2" />
        </Style>
    </UserControl.Resources>
    
    <StackPanel>
        <ContentControl Content="Live.com Search Suggestions" Style="{StaticResource Header}" />

        <!-- AutoCompleteBox example -->
        <Grid Width="650" Height="406" Background="{StaticResource SearchSuggestionsImageBrush}">
            <StackPanel Height="34" Width="490" Orientation="Horizontal" VerticalAlignment="Top" Margin="80,119,80,0">
                <TextBlock FontSize="18" FontFamily="Verdana" VerticalAlignment="Center"><Run Text="Live Search"/></TextBlock>
                <Grid Width="360" Height="34" Margin="8,0,0,0">

                    <input:AutoCompleteBox 
                        FilterMode="None"
                        x:Name="Search" 
                        TextBoxStyle="{StaticResource SearchTextBoxStyle}"
                        IsEnabled="False" />
                    <Button x:Name="Go" Cursor="Hand" IsEnabled="False" Width="32" Height="32" HorizontalAlignment="Right" BorderThickness="0,0,0,0" RenderTransformOrigin="0.5,0.5">
                        <Button.RenderTransform>
                            <TransformGroup>
                                <ScaleTransform ScaleX="0.85" ScaleY="0.85"/>
                                <SkewTransform/>
                                <RotateTransform/>
                                <TranslateTransform/>
                            </TransformGroup>
                        </Button.RenderTransform>
                        <Button.Template>
                            <ControlTemplate TargetType="Button">
                                <Grid Margin="0" x:Name="RootElement">
                                    <Rectangle Margin="0" Fill="#FF549C00" Stroke="#FF000000" StrokeThickness="0" RadiusX="2.5" RadiusY="2.5"/>
                                    <Ellipse Height="16.105" Margin="0,6.438,5,0" VerticalAlignment="Top" Stroke="#FFFFFFFF" StrokeThickness="2" Width="15.938" HorizontalAlignment="Right"/>
                                    <Path Height="7.875" HorizontalAlignment="Left" Margin="7.754,0,0,6.467" VerticalAlignment="Bottom" Width="7.75" Fill="#FFFFFFFF" Stretch="Fill" Stroke="#FFFFFFFF" StrokeThickness="2" Data="M14.097251,19.182762 L8.7665224,24.552877"/>
                                </Grid>
                            </ControlTemplate>
                        </Button.Template>
                    </Button>
                </Grid>
            </StackPanel>


            <!-- Hosting warning message -->
            <StackPanel x:Name="HostingWarning" Background="#88000000">
                <StackPanel Background="#aaffffff" Margin="6">
                    <TextBlock Margin="6" UseLayoutRounding="False" FontWeight="Bold">This sample must be hosted on a web server.</TextBlock>
                    <TextBlock Margin="6" UseLayoutRounding="False" TextWrapping="Wrap">A cross-domain web service call can only be made when the page is hosted from a server via the HTTP scheme. Consider hosting this using IIS, the built-in Web Development Server in Visual Studio, or another server technology.</TextBlock>
                </StackPanel>
            </StackPanel>

        </Grid>

        <src:SourceViewer xmlns:src="clr-namespace:System.Windows.Controls.Samples;assembly=System.Windows.Controls.Samples.Common" xmlns:sys="clr-namespace:System;assembly=mscorlib">
  <src:SourceFile Path="SearchSuggestionSample.xaml">
    <src:SourceFile.Source>
      <sys:String>&lt;!--
// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
--&gt;

&lt;UserControl x:Class="System.Windows.Controls.Samples.SearchSuggestionSample"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:system="clr-namespace:System;assembly=mscorlib"
    xmlns:samplesCommon="clr-namespace:System.Windows.Controls.Samples;assembly=System.Windows.Controls.Samples.Common"
    xmlns:input="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input"&gt;

    &lt;UserControl.Resources&gt;
        &lt;Style x:Key="SearchTextBoxStyle" TargetType="TextBox"&gt;
            &lt;Setter Property="Background" Value="#AAFFFFFF" /&gt;
            &lt;Setter Property="FontFamily" Value="Verdana" /&gt;
            &lt;Setter Property="FontSize" Value="18" /&gt;
            &lt;Setter Property="Padding" Value="2" /&gt;
        &lt;/Style&gt;
    &lt;/UserControl.Resources&gt;
    
    &lt;StackPanel&gt;
        &lt;ContentControl Content="Live.com Search Suggestions" Style="{StaticResource Header}" /&gt;

        &lt;!-- AutoCompleteBox example --&gt;
        &lt;Grid Width="650" Height="406" Background="{StaticResource SearchSuggestionsImageBrush}"&gt;
            &lt;StackPanel Height="34" Width="490" Orientation="Horizontal" VerticalAlignment="Top" Margin="80,119,80,0"&gt;
                &lt;TextBlock FontSize="18" FontFamily="Verdana" VerticalAlignment="Center"&gt;&lt;Run Text="Live Search"/&gt;&lt;/TextBlock&gt;
                &lt;Grid Width="360" Height="34" Margin="8,0,0,0"&gt;

                    &lt;input:AutoCompleteBox 
                        FilterMode="None"
                        x:Name="Search" 
                        TextBoxStyle="{StaticResource SearchTextBoxStyle}"
                        IsEnabled="False" /&gt;
                    &lt;Button x:Name="Go" Cursor="Hand" IsEnabled="False" Width="32" Height="32" HorizontalAlignment="Right" BorderThickness="0,0,0,0" RenderTransformOrigin="0.5,0.5"&gt;
                        &lt;Button.RenderTransform&gt;
                            &lt;TransformGroup&gt;
                                &lt;ScaleTransform ScaleX="0.85" ScaleY="0.85"/&gt;
                                &lt;SkewTransform/&gt;
                                &lt;RotateTransform/&gt;
                                &lt;TranslateTransform/&gt;
                            &lt;/TransformGroup&gt;
                        &lt;/Button.RenderTransform&gt;
                        &lt;Button.Template&gt;
                            &lt;ControlTemplate TargetType="Button"&gt;
                                &lt;Grid Margin="0" x:Name="RootElement"&gt;
                                    &lt;Rectangle Margin="0" Fill="#FF549C00" Stroke="#FF000000" StrokeThickness="0" RadiusX="2.5" RadiusY="2.5"/&gt;
                                    &lt;Ellipse Height="16.105" Margin="0,6.438,5,0" VerticalAlignment="Top" Stroke="#FFFFFFFF" StrokeThickness="2" Width="15.938" HorizontalAlignment="Right"/&gt;
                                    &lt;Path Height="7.875" HorizontalAlignment="Left" Margin="7.754,0,0,6.467" VerticalAlignment="Bottom" Width="7.75" Fill="#FFFFFFFF" Stretch="Fill" Stroke="#FFFFFFFF" StrokeThickness="2" Data="M14.097251,19.182762 L8.7665224,24.552877"/&gt;
                                &lt;/Grid&gt;
                            &lt;/ControlTemplate&gt;
                        &lt;/Button.Template&gt;
                    &lt;/Button&gt;
                &lt;/Grid&gt;
            &lt;/StackPanel&gt;


            &lt;!-- Hosting warning message --&gt;
            &lt;StackPanel x:Name="HostingWarning" Background="#88000000"&gt;
                &lt;StackPanel Background="#aaffffff" Margin="6"&gt;
                    &lt;TextBlock Margin="6" UseLayoutRounding="False" FontWeight="Bold"&gt;This sample must be hosted on a web server.&lt;/TextBlock&gt;
                    &lt;TextBlock Margin="6" UseLayoutRounding="False" TextWrapping="Wrap"&gt;A cross-domain web service call can only be made when the page is hosted from a server via the HTTP scheme. Consider hosting this using IIS, the built-in Web Development Server in Visual Studio, or another server technology.&lt;/TextBlock&gt;
                &lt;/StackPanel&gt;
            &lt;/StackPanel&gt;

        &lt;/Grid&gt;
      
    &lt;/StackPanel&gt;
&lt;/UserControl&gt;
</sys:String>
    </src:SourceFile.Source>
  </src:SourceFile>
  <src:SourceFile Path="SearchSuggestionSample.xaml.cs">
    <src:SourceFile.Source>
      <sys:String>// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Json;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Browser;
using System.Windows.Controls;
using System.ComponentModel;

namespace System.Windows.Controls.Samples
{
    /// &lt;summary&gt;
    /// A simple auto complete search suggestions sample that connects to a 
    /// real web service.
    /// &lt;/summary&gt;
    [Sample("Search Suggestions", DifficultyLevel.Scenario)]
    [Category("AutoCompleteBox")]
    public partial class SearchSuggestionSample : UserControl
    {
        /// &lt;summary&gt;
        /// Initializes a new instance of the SearchSuggestionSample class.
        /// &lt;/summary&gt;
        public SearchSuggestionSample()
        {
            InitializeComponent();
            Loaded += OnLoaded;
        }

        /// &lt;summary&gt;
        /// Handles the Loaded event by initializing the control for live web 
        /// service use if the stack is available.
        /// &lt;/summary&gt;
        /// &lt;param name="sender"&gt;The source object.&lt;/param&gt;
        /// &lt;param name="e"&gt;The event data.&lt;/param&gt;
        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            if (WebServiceHelper.CanMakeHttpRequests)
            {
                HostingWarning.Visibility = Visibility.Collapsed;
                Go.IsEnabled = true;
                Search.IsEnabled = true;

                Search.Populating += Search_Populating;
                Action go = () =&gt; HtmlPage.Window.Navigate(WebServiceHelper.CreateWebSearchUri(Search.Text), "_blank");
                Search.KeyUp += (s, args) =&gt;
                    {
                        if (args.Key == System.Windows.Input.Key.Enter)
                        {
                            go();
                        }
                    };
                Go.Click += (s, args) =&gt; go();
            }
        }

        /// &lt;summary&gt;
        /// Handle and cancel the Populating event, and kick off the web service
        /// request.
        /// &lt;/summary&gt;
        /// &lt;param name="sender"&gt;The source object.&lt;/param&gt;
        /// &lt;param name="e"&gt;The event data.&lt;/param&gt;
        private void Search_Populating(object sender, PopulatingEventArgs e)
        {
            AutoCompleteBox autoComplete = (AutoCompleteBox)sender;

            // Allow us to wait for the response
            e.Cancel = true;

            // Create a request for suggestion
            WebClient wc = new WebClient();
            wc.DownloadStringCompleted += OnDownloadStringCompleted;
            wc.DownloadStringAsync(WebServiceHelper.CreateWebSearchSuggestionsUri(autoComplete.SearchText), autoComplete);
        }

        /// &lt;summary&gt;
        /// Handle the string download completed event of WebClient.
        /// &lt;/summary&gt;
        /// &lt;param name="sender"&gt;The source object.&lt;/param&gt;
        /// &lt;param name="e"&gt;The event data.&lt;/param&gt;
        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Any failure in the Json or request parsing should not be surfaced.")]
        private void OnDownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            AutoCompleteBox autoComplete = e.UserState as AutoCompleteBox;
            if (autoComplete != null &amp;&amp; e.Error == null &amp;&amp; !e.Cancelled &amp;&amp; !string.IsNullOrEmpty(e.Result))
            {
                List&lt;string&gt; data = new List&lt;string&gt;();
                try
                {
                    JsonObject jso = ((JsonObject)JsonObject.Parse(e.Result))["SearchSuggestion"] as JsonObject;
                    string originalSearchString = jso["Query"];
                    if (originalSearchString == autoComplete.SearchText)
                    {
                        foreach (JsonObject suggestion in (JsonArray)jso["Section"])
                        {
                            data.Add(suggestion.Values.First());
                        }

                        // Diplay the AutoCompleteBox drop down with any suggestions
                        autoComplete.ItemsSource = data;
                        autoComplete.PopulateComplete();
                    }
                }
                catch
                {
                }
            }
        }
    }
}</sys:String>
    </src:SourceFile.Source>
  </src:SourceFile>
  <src:SourceFile Path="SearchSuggestionSample.xaml.vb">
    <src:SourceFile.Source>
      <sys:String>' (c) Copyright Microsoft Corporation.
' This source is subject to the Microsoft Public License (Ms-PL).
' Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
' All other rights reserved.

Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.Diagnostics.CodeAnalysis
Imports System.Json
Imports System.Linq
Imports System.Net
Imports System.Windows
Imports System.Windows.Browser
Imports System.Windows.Controls
Imports System.ComponentModel

''' &lt;summary&gt;
''' A simple auto complete search suggestions sample that connects to a 
''' real web service.
''' &lt;/summary&gt;
&lt;Sample("Search Suggestions", DifficultyLevel.Scenario), Category("AutoCompleteBox")&gt; _
Partial Public Class SearchSuggestionSample
    Inherits UserControl
    ''' &lt;summary&gt;
    ''' Initializes a new instance of the SearchSuggestionSample class.
    ''' &lt;/summary&gt;
    Public Sub New()
        InitializeComponent()
    End Sub

    ''' &lt;summary&gt;
    ''' Handles the Loaded event by initializing the control for live web 
    ''' service use if the stack is available.
    ''' &lt;/summary&gt;
    ''' &lt;param name="sender"&gt;The source object.&lt;/param&gt;
    ''' &lt;param name="e"&gt;The event data.&lt;/param&gt;
    Private Sub OnLoaded(ByVal sender As Object, ByVal e As RoutedEventArgs) Handles Me.Loaded
        If WebServiceHelper.CanMakeHttpRequests Then
            HostingWarning.Visibility = Visibility.Collapsed
            Go.IsEnabled = True
            Search.IsEnabled = True
        End If
    End Sub

    ''' &lt;summary&gt;
    ''' Handle and cancel the Populating event, and kick off the web service
    ''' request.
    ''' &lt;/summary&gt;
    ''' &lt;param name="sender"&gt;The source object.&lt;/param&gt;
    ''' &lt;param name="e"&gt;The event data.&lt;/param&gt;
    Private Sub Search_Populating(ByVal sender As Object, ByVal e As PopulatingEventArgs) Handles Search.Populating
        Dim autoComplete As AutoCompleteBox = CType(sender, AutoCompleteBox)

        ' Allow us to wait for the response
        e.Cancel = True

        ' Create a request for suggestion
        Dim wc As New WebClient()
        AddHandler wc.DownloadStringCompleted, AddressOf OnDownloadStringCompleted
        wc.DownloadStringAsync(WebServiceHelper.CreateWebSearchSuggestionsUri(autoComplete.SearchText), autoComplete)
    End Sub

    ''' &lt;summary&gt;
    ''' Handle the AutoCompleteBox KeyUp event, and kick off the web service
    ''' request when the Enter key is pressed.
    ''' &lt;/summary&gt;
    ''' &lt;param name="sender"&gt;The source object.&lt;/param&gt;
    ''' &lt;param name="e"&gt;The event data.&lt;/param&gt;
    Private Sub Search_KeyUp(ByVal sender As Object, ByVal e As Input.KeyEventArgs) Handles Search.KeyUp
        If e.Key = System.Windows.Input.Key.Enter Then
            CallWebServiceWithSearchString(Search.Text)
        End If
    End Sub

    ''' &lt;summary&gt;
    ''' Handle the Go button Click event, and kick off the web service
    ''' request.
    ''' &lt;/summary&gt;
    ''' &lt;param name="sender"&gt;The source object.&lt;/param&gt;
    ''' &lt;param name="e"&gt;The event data.&lt;/param&gt;
    Private Sub Go_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) Handles Go.Click
        CallWebServiceWithSearchString(Search.Text)
    End Sub

    ''' &lt;summary&gt;
    ''' Kick off the web service request.
    ''' &lt;/summary&gt;
    ''' &lt;param name="searchText"&gt;The search text.&lt;/param&gt;
    Private Shared Sub CallWebServiceWithSearchString(ByRef searchText As String)
        HtmlPage.Window.Navigate(WebServiceHelper.CreateWebSearchUri(searchText), "_blank")
    End Sub

    ''' &lt;summary&gt;
    ''' Handle the string download completed event of WebClient.
    ''' &lt;/summary&gt;
    ''' &lt;param name="sender"&gt;The source object.&lt;/param&gt;
    ''' &lt;param name="e"&gt;The event data.&lt;/param&gt;
    &lt;SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification:="Any failure in the Json or request parsing should not be surfaced.")&gt; _
    Private Sub OnDownloadStringCompleted(ByVal sender As Object, ByVal e As DownloadStringCompletedEventArgs)
        Dim autoComplete As AutoCompleteBox = TryCast(e.UserState, AutoCompleteBox)
        If autoComplete IsNot Nothing AndAlso e.Error Is Nothing AndAlso (Not e.Cancelled) AndAlso (Not String.IsNullOrEmpty(e.Result)) Then
            Dim data As List(Of String) = New List(Of String)()
            Try
                Dim jso As JsonObject = TryCast((CType(JsonObject.Parse(e.Result), JsonObject))("SearchSuggestion"), JsonObject)
                Dim originalSearchString As String = jso("Query")
                If originalSearchString = autoComplete.SearchText Then
                    For Each suggestion As JsonObject In CType(jso("Section"), JsonArray)
                        data.Add(suggestion.Values.First())
                    Next suggestion

                    ' Diplay the AutoCompleteBox drop down with any suggestions
                    autoComplete.ItemsSource = data
                    autoComplete.PopulateComplete()
                End If
            Catch
            End Try
        End If
    End Sub
End Class
</sys:String>
    </src:SourceFile.Source>
  </src:SourceFile>
</src:SourceViewer>
      
    </StackPanel>
</UserControl>
